package com.cn.ant.modules.wechat.service;

import com.cn.ant.common.log.LogUtil;
import com.cn.ant.common.utils.DateUtils;
import com.cn.ant.common.utils.StringUtils;
import com.cn.ant.modules.wechat.entity.*;
import com.cn.ant.modules.wechat.entity.message.resp.Article;
import com.cn.ant.modules.wechat.entity.message.resp.NewsMessageResp;
import com.cn.ant.modules.wechat.entity.message.resp.TextMessageResp;
import com.cn.ant.modules.wechat.service.function.KeyServiceI;
import com.cn.ant.modules.wechat.service.function.impl.SiHaiService;
import com.cn.ant.modules.wechat.utils.MessageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.*;

/**
 * 微信核心处理类
 * Created by AntDream on 2015/3/22.
 */
@Service("wechatService")
public class WechatService {
    @Autowired
    private WeixinAccountServiceImpl weixinAccountService;
    @Autowired
    private ReceiveTextService receiveTextService;
    @Autowired
    private AutoResponseService autoResponseService;
    @Autowired
    private TextTemplateService textTemplateService;
    @Autowired
    private NewsItemService newsItemService;
    @Autowired
    private NewsTemplateService newsTemplateService;
    @Autowired
    private WeixinExpandconfigService expandconfigService;
    @Autowired
    private SubscribeService subscribeService;
    @Autowired
    private MenuEntityService menuEntityService;
    @Autowired
    private WeiXinNewListItemService newListItemService;

    public String coreService(HttpServletRequest request) {
        String respMessage = null;
        try {
            // 默认返回的文本消息内容
            String respContent = "请求处理异常，请稍候尝试！";
            // xml请求解析
            Map<String, String> requestMap = MessageUtil.parseXml(request);
            // 发送方帐号（open_id）
            String fromUserName = requestMap.get("FromUserName");
            // 公众帐号
            String toUserName = requestMap.get("ToUserName");
            // 消息类型
            String msgType = requestMap.get("MsgType");
            String msgId = requestMap.get("MsgId");
            //消息内容
            String content = requestMap.get("Content");
            LogUtil.info("------------微信客户端发送请求---------------------   |   fromUserName:" + fromUserName + "   |   ToUserName:" + toUserName + "   |   msgType:" + msgType + "   |   msgId:" + msgId + "   |   content:" + content);
            //根据微信ID,获取配置的全局的数据权限ID
            LogUtil.info("-toUserName--------" + toUserName);
            String sys_accountId = weixinAccountService.findByToUsername(toUserName).getId();
            LogUtil.info("-sys_accountId--------" + sys_accountId);
            ResourceBundle bundler = ResourceBundle.getBundle("application");//获取系统配置文件
            // 默认回复此文本消息
            TextMessageResp textMessage = new TextMessageResp();
            textMessage.setToUserName(fromUserName);
            textMessage.setFromUserName(toUserName);
            textMessage.setCreateTime(new Date().getTime());
            textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
            textMessage.setContent(getMainMenu());
            // 将文本消息对象转换成xml字符串
            respMessage = MessageUtil.textMessageToXml(textMessage);
            //【微信触发类型】文本消息
            if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
                LogUtil.info("------------微信客户端发送请求------------------【微信触发类型】文本消息---");
                respMessage = doTextResponse(content, toUserName, textMessage, bundler,
                        sys_accountId, respMessage, fromUserName, request, msgId, msgType);
            }
            //【微信触发类型】图片消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
                respContent = "您发送的是图片消息！";
            }
            //【微信触发类型】地理位置消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
                respContent = "您发送的是地理位置消息！";
            }
            //【微信触发类型】链接消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
                respContent = "您发送的是链接消息！";
            }
            //【微信触发类型】音频消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
                respContent = "您发送的是音频消息！";
            }
            //【微信触发类型】事件推送
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
                LogUtil.info("------------微信客户端发送请求------------------【微信触发类型】事件推送---");
                // 事件类型
                String eventType = requestMap.get("Event");
                // 订阅
                if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                    // TODO
                    respMessage = doDingYueEventResponse(requestMap, textMessage, bundler, respMessage, toUserName, fromUserName, respContent, sys_accountId);
                }
                // 取消订阅
                else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
                    // TODO 取消订阅后用户再收不到公众号发送的消息，因此不需要回复消息
                }
                // 自定义菜单点击事件
                else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
                    // TODO
                    respMessage = doMyMenuEvent(requestMap, textMessage, bundler, respMessage, toUserName, fromUserName, respContent, sys_accountId, request);
                }else if (eventType.equals(MessageUtil.EVENT_TYPE_VIEW)) {
                    String eventKey = requestMap.get("EventKey");
                    request.setAttribute("key", "key");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return respMessage;
    }

    /**
     * 针对文本消息
     *
     * @param content
     * @param toUserName
     * @param textMessage
     * @param bundler
     * @param sys_accountId
     * @param respMessage
     * @param fromUserName
     * @param request
     * @throws Exception
     */
    String doTextResponse(String content, String toUserName, TextMessageResp textMessage, ResourceBundle bundler,
                          String sys_accountId, String respMessage, String fromUserName, HttpServletRequest request, String msgId, String msgType) throws Exception {
        //=================================================================================================================
        // 保存接收到的信息
        ReceiveText receiveText = new ReceiveText();
        receiveText.setContent(content);
        Timestamp temp = Timestamp.valueOf(DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
        receiveText.setCreatetime(temp);
        receiveText.setFromusername(fromUserName);
        receiveText.setTousername(toUserName);
        receiveText.setMsgid(msgId);
        receiveText.setMsgtype(msgType);
        receiveText.setResponse("0");
        receiveText.setAccountid(toUserName);
        receiveTextService.save(receiveText);
        //=================================================================================================================
        //Step.1 判断关键字信息中是否管理该文本内容。有的话优先采用数据库中的回复
        LogUtil.info("------------微信客户端发送请求--------------");
        LogUtil.info("Step.1 判断关键字信息中是否管理该文本内容。有的话优先采用数据库中的回复---");
        AutoResponse autoResponse = findKey(content, toUserName);
        // 根据系统配置的关键字信息，返回对应的消息
        if (autoResponse != null) {
            String resMsgType = autoResponse.getMsgtype();
            if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(resMsgType)) {
                //根据返回消息key，获取对应的文本消息返回给微信客户端
                Map<String, Object> param = new HashMap<>();
                param.put("accountid", sys_accountId);
                param.put("templatename", autoResponse.getTemplatename());
                List<TextTemplate> tempList = textTemplateService.queryForList(param);
                TextTemplate textTemplate = tempList.get(0);
                textMessage.setContent(textTemplate.getContent());
                respMessage = MessageUtil.textMessageToXml(textMessage);
            } else if (MessageUtil.RESP_MESSAGE_TYPE_NEWS.equals(resMsgType)) {
                Map<String, Object> param = new HashMap<>();
                List<NewsItem> newsList = newsItemService.findByTemplateId(autoResponse.getRescontent());
                NewsTemplate newsTemplate = newsTemplateService.get(autoResponse.getRescontent());
                List<Article> articleList = new ArrayList<Article>();
                for (NewsItem news : newsList) {
                    Article article = new Article();
                    article.setTitle(news.getTitle());
                    article.setPicUrl(bundler.getString("domain") + "/" + news.getImagepath());
                    String url = "";
                    if (StringUtils.isEmpty(news.getUrl())) {
                        url = bundler.getString("domain") + "/newsItemController.do?newscontent&id=" + news.getId();
                    } else {
                        url = news.getUrl();
                    }
                    article.setUrl(url);
                    article.setDescription(news.getDescription());
                    articleList.add(article);
                }
                NewsMessageResp newsResp = new NewsMessageResp();
                newsResp.setCreateTime(new Date().getTime());
                newsResp.setFromUserName(toUserName);
                newsResp.setToUserName(fromUserName);
                newsResp.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
                newsResp.setArticleCount(newsList.size());
                newsResp.setArticles(articleList);
                respMessage = MessageUtil.newsMessageToXml(newsResp);
            }
        } else {
            // Step.2  通过微信扩展接口（支持二次开发，例如：翻译，天气）
            LogUtil.info("------------微信客户端发送请求-----------------");
            LogUtil.info("Step.2  通过微信扩展接口（支持二次开发，例如：翻译，天气）");
            List<WeixinExpandconfig> weixinExpandconfigEntityLst = expandconfigService.queryAll();
            if (weixinExpandconfigEntityLst.size() != 0) {
                for (WeixinExpandconfig wec : weixinExpandconfigEntityLst) {
                    boolean findflag = false;// 是否找到关键字信息
                    // 如果已经找到关键字并处理业务，结束循环。
                    if (findflag) {
                        break;// 如果找到结束循环
                    }
                    String[] keys = wec.getKeyword().split(",");
                    for (String k : keys) {
                        if (content.indexOf(k) != -1) {
                            String className = wec.getClassname();
                            KeyServiceI keyService = (KeyServiceI) Class.forName(className).newInstance();
                            respMessage = keyService.excute(content, textMessage, request);
                            findflag = true;// 改变标识，已经找到关键字并处理业务，结束循环。
                            break;// 当前关键字信息处理完毕，结束当前循环
                        }
                    }
                }
            }
        }
        return respMessage;
    }

    /**
     * 遍历关键字管理中是否存在用户输入的关键字信息
     *
     * @param content
     * @return
     */
    private AutoResponse findKey(String content, String toUsername) {
        LogUtil.info("---------toUsername--------" + toUsername + "|");
        //获取全局的数据权限ID
        String sys_accountId = weixinAccountService.findByToUsername(toUsername).getId();
        LogUtil.info("---------sys_accountId--------" + sys_accountId);
        // 获取关键字管理的列表，匹配后返回信息
        Map<String, Object> param = new HashMap<>();
        param.put("accountid", sys_accountId);
        List<AutoResponse> autoResponses = autoResponseService.query(param);
        LogUtil.info("---------sys_accountId----关键字查询结果条数：----" + autoResponses != null ? autoResponses.size() : 0);
        for (AutoResponse r : autoResponses) {
            // 如果包含关键字
            String kw = r.getKeyword();
            String[] allkw = kw.split(",");
            for (String k : allkw) {
                if (k.equals(content)) {
                    LogUtil.info("---------sys_accountId----查询结果----" + r);
                    return r;
                }
            }
        }
        return null;
    }

    /**
     * 针对事件消息
     * @param requestMap
     * @param textMessage
     * @param bundler
     * @param respMessage
     * @param toUserName
     * @param fromUserName
     */
    String doDingYueEventResponse(Map<String, String> requestMap,TextMessageResp textMessage ,ResourceBundle bundler,String respMessage
            ,String toUserName,String fromUserName,String respContent,String sys_accountId){
        respContent = "谢谢您的关注！回复\"?\"进入主菜单。";
        Map<String, Object> param = new HashMap<>();
        param.put("accountid", sys_accountId);
        List<Subscribe> lst = subscribeService.queryForList(param);
        if (lst.size() != 0) {
            Subscribe subscribe = lst.get(0);
            String type = subscribe.getMsgtype();
            if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(type)) {
                TextTemplate textTemplate = textTemplateService.findByTemplateId(subscribe.getTemplateid());
                String content = textTemplate.getContent();
                textMessage.setContent(content);
                respMessage = MessageUtil.textMessageToXml(textMessage);
            } else if (MessageUtil.RESP_MESSAGE_TYPE_NEWS.equals(type)) {
                List<NewsItem> newsList = newsItemService.findByTemplateId(subscribe.getTemplateid());
                List<Article> articleList = new ArrayList<Article>();
                NewsTemplate newsTemplate = newsTemplateService.get(subscribe.getTemplateid());
                for (NewsItem news : newsList) {
                    Article article = new Article();
                    article.setTitle(news.getTitle());
                    article.setPicUrl(bundler.getString("domain") + "/" + news.getImagepath());
                    String url = "";
                    if ("commond".equals(newsTemplate.getType())) {
                        url = bundler.getString("domain") + "/newsItemController.do?newscontent&id=" + news.getId();
                    } else {
                        url = news.getContent();
                    }
                    article.setUrl(url);
                    article.setDescription(news.getContent());
                    articleList.add(article);
                }
                NewsMessageResp newsResp = new NewsMessageResp();
                newsResp.setCreateTime(new Date().getTime());
                newsResp.setFromUserName(toUserName);
                newsResp.setToUserName(fromUserName);
                newsResp.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
                newsResp.setArticleCount(newsList.size());
                newsResp.setArticles(articleList);
                respMessage = MessageUtil.newsMessageToXml(newsResp);
            }
        }
        return respMessage;
    }

    /**
     *
     * @param requestMap
     * @param textMessage
     * @param bundler
     * @param respMessage
     * @param toUserName
     * @param fromUserName
     * @param respContent
     * @param sys_accountId
     * @param request
     * @return
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    String doMyMenuEvent(Map<String, String> requestMap,TextMessageResp textMessage ,ResourceBundle bundler,String respMessage
            ,String toUserName,String fromUserName,String respContent,String sys_accountId,HttpServletRequest request) throws Exception{
        String key = requestMap.get("EventKey");
        //自定义菜单CLICK类型
        MenuEntity menuEntity = menuEntityService.findByMenuKey(key);
        if (menuEntity != null&& StringUtils.isNotEmpty(menuEntity.getTemplateid())) {
            String type = menuEntity.getMsgtype();
            if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(type)) {
                TextTemplate textTemplate = textTemplateService.get(menuEntity.getTemplateid());
                String content = textTemplate.getContent();
                textMessage.setContent(content);
                respMessage = MessageUtil.textMessageToXml(textMessage);
            } else if (MessageUtil.RESP_MESSAGE_TYPE_NEWS.equals(type)) {
                //根据模板获取条目信息
                List<WeiXinNewListItem> newItemList = newListItemService.queryByTypeId(menuEntity.getTemplateid());
                List<Article> articleList = new ArrayList<Article>();
                for (WeiXinNewListItem news : newItemList) {
                    Article article = new Article();
                    article.setTitle(news.getTitle());
                    article.setPicUrl(news.getPicUrl());
                    String url = news.getUrl();
                    article.setUrl(url);
                    article.setDescription(news.getDescription());
                    articleList.add(article);
                }
                NewsMessageResp newsResp = new NewsMessageResp();
                newsResp.setCreateTime(new Date().getTime());
                newsResp.setFromUserName(toUserName);
                newsResp.setToUserName(fromUserName);
                newsResp.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
                newsResp.setArticleCount(newItemList.size());
                newsResp.setArticles(articleList);
                respMessage = MessageUtil.newsMessageToXml(newsResp);
            } else if ("expend".equals(type)) {
                /*
                WeixinExpandconfig expandconfigEntity = expandconfigService.get(menuEntity.getTemplateid());
                String className = expandconfigEntity.getClassname();
                KeyServiceI keyService = (KeyServiceI) Class.forName(className).newInstance();
                */
                KeyServiceI keyService = new SiHaiService();
                respMessage = keyService.excute("", textMessage,request);
            }
        }
        return respMessage;
    }

    /**
     * 欢迎语
     *
     * @return
     */
    public static String getMainMenu() {
        // 复杂字符串文本读取，采用文件方式存储
        //String html = FreeMarkers.parseTemplate("/ftls/welcome.ftl", null);
        String html = "欢迎关注我";
        return html;
    }
}
